home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1998 November: Tool Chest / Dev.CD Nov 98 TC.toast / Tool Chest / QuickDraw / Virtual Sphere 1.0.1 / Virtual Sphere Sample Code 1.1 / VirtualSphere.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-03-25  |  3.3 KB  |  88 lines  |  [TEXT/MPS ]

  1. /*•••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••
  2. /* VirtualSphere.c
  3. /*
  4. /* Implements the Virtual Sphere algorithm for 3D rotation using a 2D input device.
  5. /* See paper "A Study in Interactive 3-D Rotation Using 2-D Control Devices" by
  6. /* Michael Chen, S. Joy Mountford and Abigail Sellen published in the ACM Siggraph '88
  7. /* proceedings (Volume 22, Number 4, August 1988) for more detail.  The code here
  8. /* provides a much simpler implementation than that described in the paper.
  9. /*
  10. /* Author: Michael Chen, Human Interface Group / ATG
  11. /* Copyright © 1991-1993 Apple Computer, Inc.  All rights reserved.
  12. /*
  13. /* Part of Virtual Sphere Sample Code Release v1.1
  14. /*•••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••*/
  15.  
  16. #ifndef    __VIRTUALSPHERE__
  17. #include "VirtualSphere.h"
  18. #endif
  19.  
  20. /* Local routine */
  21. static void PointOnUnitSphere (Point    p,
  22.                                Point    cueCenter,
  23.                                Integer    cueRadius,
  24.                                CPoint3D    *v);
  25.  
  26. /*=================================================================================================
  27. /* VirtualSphere
  28. /* 
  29. /* Determine the axis and angle of rotation from the last 2 locations of the mouse
  30. /* relative to the Virtual Sphere cue circle.  
  31. /*-------------------------------------------------------------------------------------------------*/
  32. pascal void VirtualSphere (Point    p,    
  33.                            Point    q,
  34.                            Point    cueCenter,
  35.                            Integer    cueRadius,
  36.                            Matrix4D rotationMatrix)
  37. {
  38.     CPoint3D        op, oq;
  39.     
  40.     /* Project mouse points to 3-D points on the +z hemisphere of a unit
  41.      * sphere. */
  42.     PointOnUnitSphere (p, cueCenter, cueRadius, &op);
  43.     PointOnUnitSphere (q, cueCenter, cueRadius, &oq);
  44.  
  45.     /* Consider the two projected points as vectors from the center of the 
  46.      * unit sphere. Compute the rotation matrix that will transform vector
  47.      * op to oq. */
  48.     SetRotationMatrix (rotationMatrix, &op, &oq);
  49. }
  50.  
  51. /*=================================================================================================
  52. /* PointOnUnitSphere
  53. /*
  54. /* Project a 2D point on a circle to a 3D point on the +z hemisphere of a unit sphere.
  55. /* If the 2D point is outside the circle, it is first mapped to the nearest point on
  56. /* the circle before projection.
  57. /* Orthographic projection is used, though technically the field of view of the camera
  58. /* should be taken into account.  However, the discrepancy is neglegible.
  59. /*-------------------------------------------------------------------------------------------------*/
  60. static void PointOnUnitSphere (Point    p,
  61.                                Point    cueCenter,
  62.                                Integer    cueRadius,
  63.                                CPoint3D    *v)
  64. {
  65.     Real    length;
  66.     Real    lengthSqared;
  67.     
  68.     /* Turn the mouse points into vectors relative to the center of the circle
  69.      * and normalize them.  Note we need to flip the y value since the 3D coordinate
  70.      * has positive y going up. */
  71.     v->x = (Real)  (p.h - cueCenter.h) / (Real) cueRadius;
  72.     v->y = (Real) -(p.v - cueCenter.v) / (Real) cueRadius;
  73.  
  74.     lengthSqared = v->x*v->x + v->y*v->y;
  75.     
  76.     /* Project the point onto the sphere, assuming orthographic projection.
  77.      * Points beyond the virtual sphere are normalized onto 
  78.      * edge of the sphere (where z = 0). */
  79.     if (lengthSqared < 1.0) {
  80.         v->z = sqrt (1.0 - lengthSqared);
  81.     } else {
  82.         length = sqrt (lengthSqared);
  83.         v->x /= length;
  84.         v->y /= length;
  85.         v->z = 0.0;
  86.     }
  87. }
  88.